package com.zonski.jbots.desktop.editer;

import com.zonski.jbots.engine.Room;
import com.zonski.jbots.engine.RoomFactory;
import com.zonski.jbots.engine.Engine;
import com.zonski.jbots.game.room.AsciiRoomFactory;
import com.zonski.jbots.engine.FileInputStreamFactory;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import java.io.FileWriter;
import java.awt.*;

/**
 * Created by IntelliJ IDEA.
 * User: Chris Glover
 * Date: Oct 27, 2003
 * Time: 10:13:30 AM
 * To change this template use Options | File Templates.
 */
public class EditerOperations
{
    private File currentFile;
    private JFileChooser fileChooser;
    private RoomFactory roomFactory;
    private JLabel status;

    private JBotsEditerContext context;
    private Engine engine;

    public EditerOperations(JBotsEditerContext context, Engine engine, JLabel status)
    {
        this.status = status;
        this.context = context;
        this.engine = engine;
        this.fileChooser = new JFileChooser();
        this.roomFactory = new AsciiRoomFactory(new LiteralFileInputStreamFactory());

        this.fileChooser.addChoosableFileFilter(new FileFilter(){
            public boolean accept(File f)
            {
                return f.isDirectory() || f.getName().endsWith(".lvl");
            }

            public String getDescription()
            {
                return "Level Files (*.lvl)";
            }
        });

        /*
        this.fileChooser.addChoosableFileFilter(new FileFilter(){
            public boolean accept(File f)
            {
                return true;
            }

            public String getDescription()
            {
                return "All Files (*.*)";
            }
        });
        */
    }

    public JBotsEditerContext getContext()
    {
        return this.context;
    }

    public void newRoom()
    {
        if(this.context.getRoom() != null)
        {
            if(!this.querySave())
            {
                return;
            }
        }
        this.currentFile = null;
        try
        {
            FileInputStreamFactory streamFactory = new FileInputStreamFactory("/", "template");
            AsciiRoomFactory asciiRoomFactory = new AsciiRoomFactory(streamFactory);
            Room room = asciiRoomFactory.getRoom("new.lvl", this.engine);
            this.context.setRoom(room);
        }catch(Exception ex){
            showError("couldn't load new room template", ex);
        }
    }

    public void save()
    {
        if(this.context.getRoom() != null)
        {
            if(this.currentFile == null)
            {
                saveAs();
            }else{
                save(this.currentFile);
            }
        }
    }

    public void saveAs()
    {
        if(this.context.getRoom() != null)
        {
            int result = this.fileChooser.showSaveDialog(this.context.getComponent());
            if(result == JFileChooser.APPROVE_OPTION)
            {
                save(this.fileChooser.getSelectedFile());
            }
        }
    }

    public void save(File file)
    {
        if(this.context.getRoom() != null)
        {
            setStatus("saving "+file.getName());
            try
            {
                FileWriter writer = new FileWriter(file);
                RoomWriter.writeRoom(this.context.getRoom(), writer);
                this.currentFile = file;
                writer.flush();
                writer.close();
            }catch(Exception ex){
                this.showError("Couldn't save to file "+file.getName(), ex);
            }
            setStatus("");
        }else{
            setStatus("no current room");
        }
    }

    public void open()
    {
        if(this.context.getRoom() != null)
        {
            if(!querySave())
            {
                return;
            }
        }
        int result = this.fileChooser.showOpenDialog(this.context.getComponent());
        if(result == JFileChooser.APPROVE_OPTION)
        {
            open(this.fileChooser.getSelectedFile());
        }
    }

    public void open(File file)
    {
        setStatus("loading "+file.getName());
        try
        {
            Room room = this.roomFactory.getRoom(file.getAbsolutePath(), engine);
            this.context.setRoom(room);
            this.currentFile = file;
            refresh();
        }catch(Exception ex){
            showError("Couldn't open file "+file.getName(), ex);
        }
        setStatus("");
    }

    public void rename()
    {
        String newName = JOptionPane.showInputDialog(this.context.getComponent(),
                "Enter the name of the rooom", this.context.getRoom().getName());
        this.context.getRoom().setName(newName);
    }

    public void remusic()
    {
        String musicName = JOptionPane.showInputDialog(this.context.getComponent(),
                "Enter the name of the music resource", this.context.getRoom().getMusic());
        this.context.getRoom().setMusic(musicName);
    }

    public void showError(String message, Exception ex)
    {
        JOptionPane.showMessageDialog(this.context.getComponent(), message+"\n"+ex, message, JOptionPane.ERROR_MESSAGE);
    }

    /**
     * Asks whether to save the current canvas or not when closing
     * @return whether or not to abort the calling operation, false abort, true continue
     */
    public boolean querySave()
    {
        int dialogResult = JOptionPane.showOptionDialog(this.context.getComponent(), "Do you want to save the current room?",
                "Save Room", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                new Object[]{"Yes", "No", "Cancel"}, "Yes");
        boolean result;
        switch(dialogResult)
        {
            default:
            case JOptionPane.CANCEL_OPTION:
                result = false;
                break;
            case JOptionPane.YES_OPTION:
                save();
                result = true;
                break;
            case JOptionPane.NO_OPTION:
                result = true;
                break;
        }
        return result;
    }

    public void setStatus(String message)
    {
        this.status.setText(message);
    }

    public void refresh()
    {
        this.context.getComponent().repaint();
    }
}
